<template>
  <div class="role-management">
    <!-- 搜索区域 -->
    <div class="search-area">
      <el-input v-model="searchForm.name" placeholder="请输入角色名称" style="width: 200px; margin-right: 10px;" />
      <el-input v-model="searchForm.code" placeholder="请输入角色编码" style="width: 200px; margin-right: 10px;" />
      <el-button type="primary" @click="handleSearch" :icon="Search">搜索</el-button>
      <el-button @click="handleReset" :icon="Refresh">重置</el-button>
      <el-button type="success" @click="handleAdd" style="margin-left: 20px;">新增角色</el-button>
    </div>

    <!-- 表格区域 -->
    <el-table :data="tableData" style="width: 100%; margin-top: 20px;" stripe border>
      <el-table-column label="序号" width="60" align="center">
        <template #default="scope">
          {{ (searchForm.pageNum - 1) * searchForm.pageSize + scope.$index + 1 }}
        </template>
      </el-table-column>
      <el-table-column prop="name" label="角色名称" width="150" align="center" />
      <el-table-column prop="code" label="角色编码" width="150" align="center" />
      <el-table-column prop="description" label="角色描述" min-width="200" align="center" />
      <el-table-column prop="createTime" label="创建时间" width="180" align="center">
        <template #default="scope">
          {{ formatDate(scope.row.createTime) }}
        </template>
      </el-table-column>
      <el-table-column prop="updateTime" label="更新时间" width="180" align="center">
        <template #default="scope">
          {{ formatDate(scope.row.updateTime) }}
        </template>
      </el-table-column>
      <el-table-column label="操作" width="280" fixed="right" align="center">
        <template #default="scope">
          <el-button type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
          <el-button type="success" size="small" @click="handlePermission(scope.row)">权限设置</el-button>
          <el-button type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <div class="pagination-container">
      <el-pagination
          v-model:current-page="searchForm.pageNum"
          v-model:page-size="searchForm.pageSize"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
      />
    </div>

    <!-- 角色表单对话框 -->
    <el-dialog
        v-model="dialogVisible"
        :title="dialogTitle"
        width="500px"
        :before-close="handleDialogClose"
        :close-on-click-modal="false"
    >
      <el-form :model="roleForm" :rules="formRules" ref="roleFormRef" label-width="100px">
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="roleForm.name" placeholder="请输入角色名称" />
        </el-form-item>
        <el-form-item label="角色编码" prop="code">
          <el-input v-model="roleForm.code" placeholder="请输入角色编码" />
        </el-form-item>
        <el-form-item label="角色描述" prop="description">
          <el-input
              v-model="roleForm.description"
              type="textarea"
              :rows="3"
              placeholder="请输入角色描述"
          />
        </el-form-item>
      </el-form>
      <template #footer>
                <span class="dialog-footer">
                    <el-button @click="handleDialogClose">取消</el-button>
                    <el-button type="primary" @click="handleSubmit">确定</el-button>
                </span>
      </template>
    </el-dialog>

    <!-- 权限设置对话框 -->
    <el-dialog
        v-model="permissionDialogVisible"
        title="权限设置"
        width="600px"
        :before-close="handlePermissionDialogClose"
        :close-on-click-modal="false"
    >
      <div class="permission-container">
        <div class="permission-header">
          <span class="role-name">角色：{{ currentRole.name }}</span>
        </div>
        <div class="menu-tree-container">
          <el-tree
              ref="menuTreeRef"
              :data="menuTreeData"
              :props="treeProps"
              show-checkbox
              node-key="id"
              :default-checked-keys="checkedMenuIds"
              :check-strictly="false"
          />
        </div>
      </div>
      <template #footer>
                <span class="dialog-footer">
                    <el-button @click="handlePermissionDialogClose">取消</el-button>
                    <el-button type="primary" @click="handlePermissionSubmit">保存权限</el-button>
                </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, Refresh } from '@element-plus/icons-vue'
import {
  getRoleList,
  addRole,
  updateRole,
  deleteRole,
  getRoleById,
  getRoleMenus,
  setRoleMenus,
  getAllMenus
} from '@/api/sys/role'

const { proxy } = getCurrentInstance()

// 搜索表单
const searchForm = reactive({
  pageNum: 1,
  pageSize: 10,
  name: '',
  code: ''
})

// 表格数据
const tableData = ref([])
const total = ref(0)

// 对话框控制
const dialogVisible = ref(false)
const dialogTitle = ref('')
const isEdit = ref(false)

// 角色表单
const roleForm = reactive({
  id: null,
  name: '',
  code: '',
  description: ''
})

// 表单验证规则
const formRules = {
  name: [
    { required: true, message: '请输入角色名称', trigger: 'blur' },
    { min: 2, max: 20, message: '角色名称长度在 2 到 20 个字符', trigger: 'blur' }
  ],
  code: [
    { required: true, message: '请输入角色编码', trigger: 'blur' },
    { min: 2, max: 20, message: '角色编码长度在 2 到 20 个字符', trigger: 'blur' },
    { pattern: /^[A-Z_]+$/, message: '角色编码只能包含大写字母和下划线', trigger: 'blur' }
  ],
  description: [
    { max: 200, message: '角色描述不能超过200个字符', trigger: 'blur' }
  ]
}

// 权限设置相关
const permissionDialogVisible = ref(false)
const currentRole = ref({})
const menuTreeData = ref([])
const checkedMenuIds = ref([])
const treeProps = {
  children: 'children',
  label: 'name'
}

// 初始化
onMounted(() => {
  loadRoleList()
})

// 加载角色列表
const loadRoleList = async () => {
  try {
    const res = await getRoleList(searchForm)
    // 添加空值检查和错误处理
    if (res && res.data) {
      tableData.value = res.data.records || []
      total.value = res.data.total || 0
    } else {
      // 如果响应结构不同，尝试直接访问
      tableData.value = res?.records || []
      total.value = res?.total || 0
    }
  } catch (error) {
    console.error('加载角色列表失败:', error)
    ElMessage.error('加载角色列表失败')
    tableData.value = []
    total.value = 0
  }
}

// 搜索
const handleSearch = () => {
  searchForm.pageNum = 1
  loadRoleList()
}

// 重置
const handleReset = () => {
  searchForm.name = ''
  searchForm.code = ''
  searchForm.pageNum = 1
  loadRoleList()
}

// 分页处理
const handleSizeChange = (val) => {
  searchForm.pageSize = val
  loadRoleList()
}

const handleCurrentChange = (val) => {
  searchForm.pageNum = val
  loadRoleList()
}

// 新增角色
const handleAdd = () => {
  isEdit.value = false
  dialogTitle.value = '新增角色'
  resetRoleForm()
  dialogVisible.value = true
}

// 编辑角色
const handleEdit = (row) => {
  isEdit.value = true
  dialogTitle.value = '编辑角色'
  Object.assign(roleForm, row)
  dialogVisible.value = true
}

// 删除角色
const handleDelete = (row) => {
  ElMessageBox.confirm(
      `确定要删除角色"${row.name}"吗？此操作不可撤销。`,
      '删除确认',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
  ).then(async () => {
    try {
      const res = await deleteRole(row.id)
      const message = res?.data || res || "删除成功"
      ElMessage.success(message)
      loadRoleList()
    } catch (error) {
      ElMessage.error('删除失败')
      console.error(error)
    }
  }).catch(() => {
    ElMessage.info('已取消删除')
  })
}

// 权限设置
const handlePermission = async (row) => {
  currentRole.value = row
  permissionDialogVisible.value = true

  try {
    // 加载所有菜单
    const allMenusRes = await getAllMenus()
    const allMenusData = allMenusRes?.data || allMenusRes || []
    menuTreeData.value = buildMenuTree(allMenusData)

    // 加载角色已有权限
    const roleMenusRes = await getRoleMenus(row.id)
    const roleMenusData = roleMenusRes?.data || roleMenusRes || []
    checkedMenuIds.value = roleMenusData.map(menu => menu.id)
  } catch (error) {
    ElMessage.error('加载权限数据失败')
    console.error(error)
  }
}

// 构建菜单树
const buildMenuTree = (menus) => {
  const menuMap = new Map()
  const rootMenus = []

  // 创建菜单映射
  menus.forEach(menu => {
    menuMap.set(menu.id, { ...menu, children: [] })
  })

  // 构建树结构
  menus.forEach(menu => {
    const menuNode = menuMap.get(menu.id)
    if (menu.parentId === 0 || !menuMap.has(menu.parentId)) {
      rootMenus.push(menuNode)
    } else {
      const parentMenu = menuMap.get(menu.parentId)
      if (parentMenu) {
        parentMenu.children.push(menuNode)
      }
    }
  })

  return rootMenus
}

// 提交权限设置
const handlePermissionSubmit = async () => {
  try {
    const checkedNodes = proxy.$refs.menuTreeRef.getCheckedNodes()
    const menuIds = checkedNodes.map(node => node.id)

    const data = {
      roleId: currentRole.value.id,
      menuIds: menuIds
    }

    const res = await setRoleMenus(data)
    const message = res?.data || res || "权限设置成功"
    ElMessage.success(message)
    permissionDialogVisible.value = false
  } catch (error) {
    ElMessage.error('保存权限失败')
    console.error(error)
  }
}

// 提交表单
const handleSubmit = () => {
  proxy.$refs.roleFormRef.validate(async (valid) => {
    if (valid) {
      try {
        let res
        if (isEdit.value) {
          res = await updateRole(roleForm)
        } else {
          res = await addRole(roleForm)
        }

        const message = res?.data || res || "操作成功"
        ElMessage.success(message)
        dialogVisible.value = false
        loadRoleList()
      } catch (error) {
        ElMessage.error('操作失败')
        console.error(error)
      }
    } else {
      ElMessage.warning('请完善表单信息')
    }
  })
}

// 重置角色表单
const resetRoleForm = () => {
  roleForm.id = null
  roleForm.name = ''
  roleForm.code = ''
  roleForm.description = ''
}

// 关闭对话框
const handleDialogClose = () => {
  dialogVisible.value = false
  proxy.$refs.roleFormRef?.resetFields()
}

// 关闭权限对话框
const handlePermissionDialogClose = () => {
  permissionDialogVisible.value = false
  currentRole.value = {}
  menuTreeData.value = []
  checkedMenuIds.value = []
}

// 格式化日期
const formatDate = (dateStr) => {
  if (!dateStr) return ''
  const date = new Date(dateStr)
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
}
</script>

<style scoped>
.role-management {
  padding: 20px;
}

.search-area {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
}

.pagination-container {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}

.permission-container {
  max-height: 400px;
  overflow-y: auto;
}

.permission-header {
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
}

.role-name {
  font-size: 16px;
  font-weight: bold;
  color: #333;
}

.menu-tree-container {
  padding: 10px;
  border: 1px solid #eee;
  border-radius: 4px;
  background-color: #fafafa;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>
